/**
 *
 */
package com.angel.architecture.services;

import org.junit.Test;

import com.angel.architecture.BaseArchitectureTestCase;
import com.angel.architecture.annotations.services.Service;
import com.angel.architecture.initializer.injector.Injector;
import com.angel.architecture.initializer.injector.impl.ServiceInjector;
import com.angel.architecture.initializer.injector.impl.SpringDAOInjector;
import com.angel.architecture.initializer.modules.ModuleDescriptor;
import com.angel.architecture.services.locator.ServiceLocator;
import com.angel.mocks.architecture.services.ADependsBService;
import com.angel.mocks.architecture.services.BDependsAService;
import com.angel.mocks.architecture.services.MockBothService;
import com.angel.mocks.architecture.services.MockDAOSpringService;
import com.angel.mocks.architecture.services.MockObjectService;
import com.angel.mocks.architecture.services.MockSpringService;

/**
 * @author William
 *
 */
public class ServiceInjectionTestCase extends BaseArchitectureTestCase {

	@Test
	public void testServicesInjectionWithSpringDependencies(){
		MockSpringService mockService = ServiceLocator.locate(MockSpringService.class);
		assertNotNull("Configuration service for \"mock service\" mustn't be null. ", mockService.getConfigurationParameterService());
		assertNotNull("User service for \"mock service\" mustn't be null. ", mockService.getUserService());
	}

	/**
	 * Test injection when a object with annotation {@link Service}, all its attributes are injected with spring configuration.
	 * In this test, its fields are setting from spring configuration, and other object services (without spring configuration).
	 *
	 *	Now this test is with assertNull because in {@link ModuleDescriptor} are commented {@link Injector}'s implementations:
	 *	{@link ServiceInjector} and {@link SpringDAOInjector}.
	 *
	 *	In resume annotation {@link Service} in angel package only allows inject beans named in the spring configuration.
	 *
	 *	It occurs in the following tests:
	 *	@see ServiceInjectionTestCase#testServicesInjectionWithBothDependencies()
	 *	@see ServiceInjectionTestCase#testServicesInjectionWithObjectDependencies()
	 *	@see ServiceInjectionTestCase#testServicesInjectionBetweenDependencies()
	 *
	 *	<p>
	 *		For more information see in the "angel" package:
	 *	</p>
	 *
	 * @see {@link Service}
	 * @see {@link ModuleDescriptor}
	 */
	@Test
	public void testServicesInjectionWithBothDependencies(){
		MockBothService toInjectService = ServiceLocator.locate(MockBothService.class);
		assertNotNull("Configuration service for \"to inject service\" mustn't be null. ", toInjectService.getConfigurationParameterService());
		assertNotNull("User service for \"to inject service\" mustn't be null. ", toInjectService.getUserService());
		assertNull("Mock service for \"to inject service\" mustn't be null. ", toInjectService.getMockService());
	}

	/**
	 * Test injection when an object with annotation @Service have all its attributes from others objects services (without spring configuration).
	 *
	 *	@see Service.
	 *	@see ServiceInjectionTestCase#testServicesInjectionWithBothDependencies()
	 */
	@Test
	public void testServicesInjectionWithObjectDependencies(){
		MockObjectService toInjectService = ServiceLocator.locate(MockObjectService.class);
		assertNull("Mock Both service for \"MockObjectService\" mustn't be null. ", toInjectService.getMockBothService());
		assertNull("Mock Spring service for \"MockObjectService\" mustn't be null. ", toInjectService.getMockSpringService());
	}

	/**
	 *	Test injection only between two object with annotation @Service.
	 *
	 *	@see Service.
	 *	@see ServiceInjectionTestCase#testServicesInjectionWithBothDependencies()
	 */
	@Test
	public void testServicesInjectionBetweenDependencies(){
		ADependsBService aDependsBService = ServiceLocator.locate(ADependsBService.class);
		assertNull("BDependsA service for \"ADependsBService\" mustn't be null. ", aDependsBService.getBDependsAService());
		BDependsAService bDependsAService = ServiceLocator.locate(BDependsAService.class);
		assertNull("aDependsB service for \"BDependsAService\" mustn't be null. ", bDependsAService.getADependsBService());
	}

	@Test
	public void testDAOsInjectionBetweenDependencies(){
		MockDAOSpringService mockDAOSpringService = ServiceLocator.locate(MockDAOSpringService.class);
		assertNotNull("Configuration Parameter DAO for \"MockDAOSpringService\" mustn't be null. ", mockDAOSpringService.getConfigurationParameterDAO());
		assertNotNull("User DAO for \"MockDAOSpringService\" mustn't be null. ", mockDAOSpringService.getUserDAO());
	}
}
